package com.itany.controller;

import com.itany.util.LockUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

/**
 * Author：汤小洋
 * Date：2023-01-31 16:44
 * Description：<描述>
 */
@RestController
public class LockController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/setStock")
    public String setStock(){
        redisTemplate.opsForValue().set("stock","50"); // 库存数量为50
        return redisTemplate.opsForValue().get("stock");
    }

    /**
     *  下单时判断库存：从redis中获取库存，检查库存数量是否够，库存数量>0才允许下单，此时库存数量-1
     */
    // @RequestMapping("/deductStock")
    // public String deductStock(){
    //     System.out.println(Thread.currentThread().getName()+"线程正在下单。。。。。。");
    //
    //     /**
    //      * 单体锁：可以保证单个实例的并发安全
    //      */
    //     synchronized (this) {
    //         int total = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
    //         if(total>0){
    //             try {
    //                 Thread.sleep(5000);
    //             } catch (InterruptedException e) {
    //                 e.printStackTrace();
    //             }
    //             total = total - 1;
    //             redisTemplate.opsForValue().set("stock", String.valueOf(total));
    //             return "下单成功，库存还剩："+total;
    //         }
    //         return "下单失败，库存不足";
    //     }
    // }


    @RequestMapping("/deductStock")
    public String deductStock(){
        System.out.println(Thread.currentThread().getName()+"线程正在下单。。。。。。");

        /**
         * 分布式锁：每个人进来都要先获取锁，也称为加锁操作
         */
        String lockName = "stock_lock"; // 锁的名称
        String value = UUID.randomUUID().toString().replace("-",""); // 锁的值
        if(! LockUtil.getLock(lockName,value)){
            return "获取锁失败！";
        }

        int total = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
        if(total>0){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            total = total - 1;
            redisTemplate.opsForValue().set("stock", String.valueOf(total));
            LockUtil.unlock(lockName,value); // 释放锁
            return "下单成功，库存还剩："+total;
        }
        LockUtil.unlock(lockName,value); // 释放锁
        return "下单失败，库存不足";
    }

}
